package org.cupk2.base.parameter.impl;

import org.cupk2.base.parameter.ParameterDomain;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CupkParameterByXml {
    private static List<ParameterDomain> paras = null;
    private static Map<String, String> valMap = new HashMap<>();
    private static Map<String, String> typeMap = new HashMap<>();
    public List<ParameterDomain> getParas() {
        return paras;
    }

    public Map<String, String> getValMap() {
        return valMap;
    }

    public Map<String, String> getTypeMap() {
        return typeMap;
    }

    public List<ParameterDomain> readConfigFromXml(String xmlFileName) {
        if (paras != null) {
            return paras;
        }
        List<ParameterDomain> cupkParameters = new ArrayList<>();
        String resourcePath = "config/" + xmlFileName + ".xml";
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        try (InputStream inputStream = classLoader.getResourceAsStream(resourcePath)) {
            if (inputStream == null) {
                throw new IllegalArgumentException("Resource not found: " + resourcePath);
            }

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();

            Document document = builder.parse(inputStream);
            document.getDocumentElement().normalize();

            NodeList groupNodes = document.getElementsByTagName("group");

            for (int i = 0; i < groupNodes.getLength(); i++) {
                Node groupNode = groupNodes.item(i);
                if (groupNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element groupElement = (Element) groupNode;

                    String groupName = groupElement.getAttribute("name");
                    String groupKey = groupElement.getAttribute("key");

                    NodeList parameterNodes = groupElement.getElementsByTagName("parameter");

                    for (int j = 0; j < parameterNodes.getLength(); j++) {
                        Node parameterNode = parameterNodes.item(j);
                        if (parameterNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element parameterElement = (Element) parameterNode;

                            String parameterName = parameterElement.getAttribute("name");
                            String parameterKey = parameterElement.getAttribute("key");
                            String parameterVersion = parameterElement.getAttribute("version");
                            String parameterVtype = parameterElement.getAttribute("vtype");
                            Boolean parameterUserable = parameterElement.getAttribute("userable").toLowerCase().equals("true");

                            String parameterVal = "";
                            String parameterDescribe = "";

                            NodeList childNodes = parameterElement.getChildNodes();
                            for (int k = 0; k < childNodes.getLength(); k++) {
                                Node childNode = childNodes.item(k);

                                if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                                    Element childElement = (Element) childNode;

                                    if ("val".equals(childElement.getTagName())) {
                                        parameterVal = childElement.getTextContent().trim();
                                    } else if ("describe".equals(childElement.getTagName())) {
                                        parameterDescribe = childElement.getTextContent().trim();
                                    }
                                }
                            }

                            ParameterDomain cupkParameter = new ParameterDomain(groupName, groupKey, parameterName, parameterKey, parameterVal, parameterDescribe, parameterVersion, parameterVtype, parameterUserable);
                            cupkParameters.add(cupkParameter);
                            valMap.put(cupkParameter.getParameterKey(), cupkParameter.getParameterVal());
                            typeMap.put(cupkParameter.getParameterKey(),cupkParameter.getParameterType());
                        }
                    }
                }
            }
        } catch (ParserConfigurationException | SAXException | IOException e) {
            throw new RuntimeException(e);
        }
        paras = cupkParameters;
        return paras;
    }
}